﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ACEPAPI
{
    /// <summary>
    /// 构建字节数组byte[]
    /// </summary>
    public class ByteArrayBuilder : IDisposable
    {
        /// <summary>
        /// True
        /// </summary>
        private const byte StreamTrue = (byte)0b_0000_0001;

        /// <summary>
        /// False
        /// </summary>
        private const byte StreamFalse = (byte)0b_0000_0000;

        /// <summary>
        /// MemoryStream
        /// </summary>
        private MemoryStream MStream = new MemoryStream();

        /// <summary>
        /// Gets bytes in the store.
        /// </summary>
        public int MStreamLength => (int)MStream.Length;

        /// <summary>
        /// 默认构造函数
        /// </summary>
        public ByteArrayBuilder()
        {

        }

        /// <summary>
        /// 在MStream后附加 byte
        /// </summary>
        /// <param name="b">字节byte</param>
        /// <returns></returns>
        public ByteArrayBuilder Append(byte b)
        {
            AddBytes(new byte[] { b });
            return this;
        }

        /// <summary>
        /// 在MStream后附加IEnumerable(byte)
        /// </summary>
        /// <param name="b">字节集合</param>
        /// </param>
        public ByteArrayBuilder Append(IEnumerable<byte> b)
        {
            if (b is byte[])
            {
                AddBytes((byte[])b);
                return this;
            }

            AddBytes(b.ToArray());
            return this;
        }
        
        public ByteArrayBuilder Append(params byte[][] array)
        {
            for (int i = 0; i < array.Length; i++)
            {
                AddBytes(array[i]);
            }
            return this;
        }
        /// <summary>
        /// 在MStream后附加byte[]数组
        /// </summary>
        /// <param name="byteArray">字节数组byte[]</param>
        private void AddBytes(byte[] byteArray)
        {
            MStream.Write(byteArray, 0, byteArray.Length);
        }
        /// <summary>
        /// 清除MStream所有数据
        /// </summary>
        public void Clear()
        {
            MStream.Close();
            MStream.Dispose();
            MStream = new MemoryStream();
        }

        /// <summary>
        /// 设置MStream游标指向开始
        /// </summary>
        public void Rewind()
        {
            MStream.Seek(0, SeekOrigin.Begin);
        }

        /// <summary>
        /// 设置MStream游标位置(由开始向结尾的位移).
        /// </summary>
        /// <param name="position">位置</param>
        public void Seek(int position)
        {
            MStream.Seek((long)position, SeekOrigin.Begin);
        }

        /// <summary>
        /// 返回MStream的byte[]形式
        /// </summary>
        /// <returns>Byte[]</returns>
        public byte[] ToArray()
        {
            byte[] data = new byte[MStreamLength];
            Array.Copy(MStream.GetBuffer(), data, MStreamLength);
            return data;
        }

        /// <summary>
        /// 返回当前内容的Base64的字符串版本
        /// </summary>
        /// <returns>String</returns>
        public override string ToString()
        {
            return Convert.ToBase64String(ToArray());
        }

        /// <summary>
        /// 从MStream开始位置读取指定长度的字节
        /// </summary>
        /// <param name="length">读取长度</param>
        /// <returns>字节数组byte[]</returns>
        private byte[] GetBytes(int length)
        {
            byte[] data;
            if (MStream.Length < length)
            {
                data = MStream.ToArray();
            }
            else
            {
                data = new byte[length];
                MStream.Read(data, 0, length);
            }
            return data;
        }

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            MStream.Close();
            MStream.Dispose();
        }
    }
}
